﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO.Ports;

namespace WPFTools.Controls
{
    
    /// <summary>
    ///  串口控件可以显示可用串口
    /// </summary>
    
    [TemplatePart(Name = "PART_CboParity",Type=typeof(ComboBox))]
    [TemplatePart(Name = "PART_CboStopBits", Type = typeof(ComboBox))]
    
    public class SerialPortControls : UserControl
    {
        private const String PART_CboParity = "PART_CboParity";
        private const String PART_CboStopBits = "PART_CboStopBits";
        /// <summary>
        /// 串口名称集合私有变量 根据电脑中获取变量
        /// </summary>
        static string[] _portNames = SerialPort.GetPortNames();
        static SerialPortControls()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(SerialPortControls), new FrameworkPropertyMetadata(typeof(SerialPortControls)));
            //将数组按照小到大排序
            if (_portNames!=null)
            {
                Array.Sort(_portNames);
            }
         }
        private ComboBox cboParity; //私有Parity下拉框的对象
        private ComboBox cboStopBits; //私有Parity下拉框的对象
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            //获取Parity下拉框对象
            cboParity = GetTemplateChild(PART_CboParity) as ComboBox;
            //初始时重新设置模板
            this.Parity = Parity;
            //关联选中事件
            cboParity.SelectionChanged += cboParity_SelectionChanged;

            //获取停止为下拉框对象
            cboStopBits = GetTemplateChild(PART_CboStopBits) as ComboBox;
            this.StopBits = StopBits;
            cboStopBits.SelectionChanged += cboStopBits_SelectionChanged;
        }

        void cboStopBits_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //获取时修改属性
            if (cboStopBits != null)
            {
                StopBits s = StopBits.One;
                switch (cboStopBits.SelectedIndex)
                {
                    case 0:
                        s = StopBits.One;
                        break;
                    case 1:
                        s = StopBits.OnePointFive;
                        break;
                    case 2:
                        s = StopBits.Two;
                        break;
                    default:
                        break;
                }
                SetValue(StopBitsProperty, s);
            }
        }

        /// <summary>
        /// 校验框刷新时刷新属性
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cboParity_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //获取时修改属性
            if (cboParity != null)
            {
                Parity p = Parity.None;
                switch (cboParity.SelectedIndex)
                {
                    case 0:
                        p = Parity.None;
                        break;
                    case 1:
                        p = Parity.Even;
                        break;
                    case 2:
                        p = Parity.Odd;
                        break;
                    case 3:
                        p = Parity.Space;
                        break;
                    case 4:
                        p = Parity.Mark;
                        break;
                    default:
                        break;
                }
                SetValue(ParityProperty, p);
            }
        }   

        /// <summary>
        /// 串口字符串列表
        /// </summary>
        public string[]  PortNames
        {
            get { return (string[])GetValue(PortNamesProperty); }
            set { SetValue(PortNamesProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PortNamesProperty =
            DependencyProperty.Register("PortNames", typeof(string[]), typeof(SerialPortControls), new PropertyMetadata(_portNames));

        /// <summary>
        /// 选择的串口号
        /// </summary>
        public String Port
        {
            get { return (String)GetValue(PortProperty); }
            set { SetValue(PortProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Port.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PortProperty =
            DependencyProperty.Register("Port", typeof(String), typeof(SerialPortControls), new PropertyMetadata(_portNames[0]));


        /// <summary>
        /// 选择的波特率
        /// </summary>
        public Int32 BaudRate
        {
            get { return (Int32)GetValue(BaudRateProperty); }
            set { SetValue(BaudRateProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BaudRate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BaudRateProperty =
            DependencyProperty.Register("BaudRate", typeof(Int32), typeof(SerialPortControls), new PropertyMetadata(9600));

 
        /// <summary>
        /// 选择的校验位  获取和设置时刷新界面
        /// </summary>
        public Parity Parity
        {
            get {   return (Parity)GetValue(ParityProperty);  }

            set 
            { 
               //设置属性是同时刷新显示cbo对象
               if (cboParity != null)
               {
                   switch (value)
                   {

                       case Parity.Even:
                           cboParity.SelectedIndex = 1;
                           break;
                       case Parity.Mark:
                           cboParity.SelectedIndex = 4;
                           break;
                       case Parity.None:
                           cboParity.SelectedIndex = 0;
                           break;
                       case Parity.Odd:
                           cboParity.SelectedIndex = 2;
                           break;
                       case Parity.Space:
                           cboParity.SelectedIndex = 3;
                           break;
                       default:
                           break;
                   }
               }
               
               SetValue(ParityProperty, value);
            }
        }

        // Using a DependencyProperty as the backing store for Parity.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ParityProperty =
            DependencyProperty.Register("Parity", typeof(Parity), typeof(SerialPortControls), new PropertyMetadata(Parity.None));

        /// <summary>
        /// 选择的数据位 
        /// </summary>

        public Int32 DataBits
        {
            get { return (Int32)GetValue(DataBitsProperty); }
            set { SetValue(DataBitsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DataBits.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataBitsProperty =
            DependencyProperty.Register("DataBits", typeof(Int32), typeof(SerialPortControls), new PropertyMetadata(8));


        /// <summary>
        /// 选择的停止位 获取和设置时刷新界面
        /// </summary>
        public StopBits StopBits
        {
            get 
            {
               
                return (StopBits)GetValue(StopBitsProperty); 
            }
            set 
            {
                //设置属性是同时刷新显示cbo对象
                if (cboStopBits != null)
                {
                    switch (value)
                    {

                        case StopBits.One:
                            cboStopBits.SelectedIndex = 0;
                            break;
                        case StopBits.OnePointFive:
                            cboStopBits.SelectedIndex = 1;
                            break;
                        case StopBits.Two:
                            cboStopBits.SelectedIndex = 2;
                            break;
                        default:
                            break;
                    }
                }
                SetValue(StopBitsProperty, value); 
            }
        }

        // Using a DependencyProperty as the backing store for StopBits.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StopBitsProperty =
            DependencyProperty.Register("StopBits", typeof(StopBits), typeof(SerialPortControls), new PropertyMetadata(StopBits.One));
    }
}
